package com.ry.est.service.impl;

import com.ry.est.constants.Constants;
import com.ry.est.dao.EvaluateDao;
import com.ry.est.dto.*;
import com.ry.est.entity.Evaluate;
import com.ry.est.entity.EvaluateDetail;
import com.ry.est.entity.Users;
import com.ry.est.service.*;
import com.ry.est.util.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.List;

/**
 * 评估业务的组件
 * @author ry
 * @since 2021-11-09 10:01
 **/
@Service
public class EvaluateServiceImpl implements EvaluateService {
    @SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
    @Autowired
    private EvaluateDao evaluateDao;

    @Autowired
    private MalfunctionService malfunctionService;

    @Autowired
    private MalfunctionOptionsService malfunctionOptionsService;

    @Autowired
    private EvaluateDetailService evaluateDetailService;

    @Autowired
    private ModelService modelService;

    /**
     * 除数
     */
    private static final BigDecimal DIVISOR = BigDecimal.valueOf(100);


    @Override
    public int saveEvaluate(Evaluate evaluate) {
        evaluate.setCreatedTime(new Date());
        evaluate.setIsDelete(Constants.EST_NOT);
        return evaluateDao.insert(evaluate);
    }

    @Override
    public EvaluateDTO assess(Long modelId, List<Long> malfuctionOptionsIds, Users users) {
        //查询故障的选项信息
        List<MalfunctionOptionsDTO> malfunctionOptionsDTOS =
                malfunctionOptionsService.listByIds(malfuctionOptionsIds);
        BigDecimal total = BigDecimal.ZERO;
        for (MalfunctionOptionsDTO malfunctionOptionsDTO : malfunctionOptionsDTOS) {
            //根据故障选项获取故障信息，取得维修最高价
            MalfunctionDTO malfunctionDTO = malfunctionService
                    .getById(malfunctionOptionsDTO.getMalfId());
            BigDecimal maintainTopPrice = malfunctionDTO.getMaintainTopPrice();
            //计算评估的维修价
            Integer processType = malfunctionOptionsDTO.getProcessType();
            //小计
            BigDecimal smallTotal = maintainTopPrice;
            if (Constants.ProcessType.MAINTAIN.equals(processType)){
                //因为ratio是一个整数，所以先乘占比值，然后再需要除以100
                smallTotal = smallTotal
                        .multiply(new BigDecimal(malfunctionOptionsDTO.getRatio()));
                smallTotal = smallTotal.divide(DIVISOR,2, RoundingMode.HALF_UP);
            }

            //计算维修总价
            total = total.add(smallTotal);
        }
        //保存评估信息
        Evaluate evaluate = new Evaluate();
        evaluate.setModelId(modelId);
        evaluate.setSubscription(total.multiply(new BigDecimal("0.1")));
        evaluate.setPrice(total);
        evaluate.setRemark("");
        evaluate.setCreatedUserId(users.getId());
        this.saveEvaluate(evaluate);
        //保存评估的详情信息
        for (MalfunctionOptionsDTO malfunctionOptionsDTO : malfunctionOptionsDTOS) {
            EvaluateDetail evaluateDetail = new EvaluateDetail();
            evaluateDetail.setEvaluateId(evaluate.getId());
            evaluateDetail.setMalfId(malfunctionOptionsDTO.getMalfId());
            evaluateDetail.setOptionId(malfunctionOptionsDTO.getId());
            evaluateDetail.setOptionName(malfunctionOptionsDTO.getOptionName());
            evaluateDetail.setCreatedUserId(users.getId());
            evaluateDetailService.saveEvaluateDetail(evaluateDetail);
        }

        return BeanUtils.convertToDTO(evaluate, EvaluateDTO.class);
    }

    @Override
    public EvaluateInfoDTO getEvaluateInfoById(Long id) {
        Evaluate evaluate = evaluateDao.selectByPrimaryKey(id);
        ModelDetailDTO modelDetailDTO = modelService
                .getById(evaluate.getModelId());
        List<EvaluateDetailDTO> evaluateDetailDTOS = evaluateDetailService
                .listByEvaluateId(evaluate.getId());

        EvaluateInfoDTO evaluateInfoDTO =
                BeanUtils.convertToDTO(evaluate, EvaluateInfoDTO.class);
        evaluateInfoDTO.setModelDetailDTO(modelDetailDTO);
        evaluateInfoDTO.setEvaluateDetailDTOS(evaluateDetailDTOS);

        return evaluateInfoDTO;
    }
}
